/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.com.deployment.manager;

import br.com.deployment.entidade.localidade.Cidade;
import br.com.deployment.entidade.registroimovel.GeoRef;
import br.com.deployment.servico.CidadeServico;
import br.com.deployment.servico.MapServico;
import br.com.deployment.util.CoordinateConversion;
import br.com.deployment.utilitario.Msg;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.event.SelectEvent;
import org.primefaces.event.map.StateChangeEvent;
import org.primefaces.model.map.*;

/**
 *
 * @author roniere
 */
@ManagedBean
@ViewScoped
public class ManagerStateCoord implements Serializable {

    @EJB
    CidadeServico cidadeServico;
    @EJB
    MapServico mapServico;
    private String convN;
    private String convE;
    private String convZona;
    private String zoomMap;
    private String centerMap;
    private List<GeoRef> lstGeoRef;
    private MapModel polygonModel;
    private Cidade cidade;

    public ManagerStateCoord() {
        this.lstGeoRef = new ArrayList<GeoRef>();
        this.polygonModel = new DefaultMapModel();
        this.centerMap = "-2.9136, -41.7577";
        this.zoomMap = "23";
        
    }

    public Cidade getCidade() {
        return cidade;
    }

    public void setCidade(Cidade cidade) {
        this.cidade = cidade;
    }

    public void converterCoord() {
        String lat = convN;
        String lon = convE;
        String zona = convZona;

        try {
            lat = lat.replace(" ", "");
            lon = lon.replace(" ", "");
            if (zona == null) {
                zona = "M";
            }

            CoordinateConversion cc = new CoordinateConversion();

            String UTM = lon.toString().substring(0, 2) + " " + zona + " " + lon.toString().substring(2) + " " + lat.toString();
            lstGeoRef.add(new GeoRef(cc.utm2LatLon(UTM)[0], cc.utm2LatLon(UTM)[1], lon, lat, zona));

        } catch (Exception e) {
            Msg.messagemError("Valores incorretos");
        }

    }

    public void initMap() {
        if (lstGeoRef.size() >= 1) {
            polygonModel = new DefaultMapModel();
            Polygon polygon = new Polygon();

            Double centerX = 0D;
            Double centerY = 0D;
            int tam = lstGeoRef.size();
            for (GeoRef geoRef : lstGeoRef) {
                if (geoRef.getLat() != 0.0 && geoRef.getLng() != 0.0) {
                    polygon.getPaths().add(new LatLng(geoRef.getLat(), geoRef.getLng()));
                    polygonModel.addOverlay(new Marker(new LatLng(geoRef.getLat(), geoRef.getLng())));
                    centerX += geoRef.getLat() / tam;
                    centerY += geoRef.getLng() / tam;
                    if (polygon.getPaths().size() == 3) {
                        calcArea(polygon);
                    }
                }
            }

            if (tam >= 4 && tam < 6) {
                zoomMap = "18";
            } else if (tam >= 6) {
                zoomMap = "14";
            } else if (tam >= 8) {
                zoomMap = "12";
            }
            centerMap = lstGeoRef.get(0).getLat() + ", " + lstGeoRef.get(0).getLng();

            polygon.setStrokeColor("#FF9900");
            polygon.setFillColor("#FF9900");
            polygon.setStrokeOpacity(0.6);
            polygon.setFillOpacity(0.5);

            polygonModel.addOverlay(polygon);

            for (Marker marker : polygonModel.getMarkers()) {
                marker.setDraggable(true);
            }
        }else{
            polygonModel = new DefaultMapModel();
            this.centerMap = "-2.9136, -41.7577";
            this.zoomMap = "23";
        }
    }

    public double calcArea(Polygon pl) {

        WKTReader reader = new WKTReader(new GeometryFactory());

        String p = "POLYGON(( ";
        for (LatLng ll : pl.getPaths()) {
            p += ll.getLat() + " " + ll.getLng() + ", ";
        }
        p += "" + pl.getPaths().get(0).getLat() + " " + pl.getPaths().get(0).getLng() + " )) ";

        com.vividsolutions.jts.geom.Polygon polygonInt = null;
        try {
            p = "POLYGON ((-2.926926 -41.751338, -2.926977 -41.751242, -2.927116 -41.751365, -2.927060 -41.751454, -2.926926 -41.751338))";
            polygonInt = (com.vividsolutions.jts.geom.Polygon) reader.read(p);
            System.err.println(polygonInt.getArea() + ": Area");
            System.err.println(polygonInt.getLength() + "LENGTH");
            System.err.println(polygonInt.getBoundary());
            System.err.println(polygonInt.getDimension());
        } catch (ParseException ex) {
            Logger.getLogger(ManagerCoord.class.getName()).log(Level.SEVERE, null, ex);
        }
        return polygonInt.getArea();

    }

    public void salvarCoord() {
        cidade = cidadeServico.find(cidade.getCod_cidade());
        cidade.setGeoRef(lstGeoRef);
        cidadeServico.atualizar(cidade);
        Msg.messagemInfo("Coordenadas do município " + cidade.getNom_cidade() + " foram atribuídas com Sucesso !");
    }

    public void onStateChange(StateChangeEvent event) {
        int zoomLevel = event.getZoomLevel();
        zoomMap = String.valueOf(zoomLevel);
    }

    public void handleSelectCidade(SelectEvent event) {
        cidade = cidadeServico.find(cidade.getCod_cidade());
        lstGeoRef = mapServico.getGeoRef(Cidade.class , cidade.getCod_cidade());
        initMap();
        
    }
    
    public void removeGeoRef(GeoRef gf) {
        this.lstGeoRef.remove(gf);
        initMap();
    }

    public String getCenterMap() {
        return centerMap;
    }

    public void setCenterMap(String centerMap) {
        this.centerMap = centerMap;
    }

    public String getConvE() {
        return convE;
    }

    public void setConvE(String convE) {
        this.convE = convE;
    }

    public String getConvN() {
        return convN;
    }

    public void setConvN(String convN) {
        this.convN = convN;
    }

    public String getConvZona() {
        return convZona;
    }

    public void setConvZona(String convZona) {
        this.convZona = convZona;
    }

    public List<GeoRef> getLstGeoRef() {
        return lstGeoRef;
    }

    public void setLstGeoRef(List<GeoRef> lstGeoRef) {
        this.lstGeoRef = lstGeoRef;
    }

    public MapModel getPolygonModel() {
        return polygonModel;
    }

    public void setPolygonModel(MapModel polygonModel) {
        this.polygonModel = polygonModel;
    }

    public String getZoomMap() {
        return zoomMap;
    }

    public void setZoomMap(String zoomMap) {
        this.zoomMap = zoomMap;
    }
}
